# LocalStack Resource Provider Scaffolding v2
from __future__ import annotations

from pathlib import Path
from typing import Optional, TypedDict

import localstack.services.cloudformation.provider_utils as util
from localstack.services.cloudformation.resource_provider import (
    OperationStatus,
    ProgressEvent,
    ResourceProvider,
    ResourceRequest,
)


class LambdaUrlProperties(TypedDict):
    AuthType: Optional[str]
    TargetFunctionArn: Optional[str]
    Cors: Optional[Cors]
    FunctionArn: Optional[str]
    FunctionUrl: Optional[str]
    InvokeMode: Optional[str]
    Qualifier: Optional[str]


class Cors(TypedDict):
    AllowCredentials: Optional[bool]
    AllowHeaders: Optional[list[str]]
    AllowMethods: Optional[list[str]]
    AllowOrigins: Optional[list[str]]
    ExposeHeaders: Optional[list[str]]
    MaxAge: Optional[int]


REPEATED_INVOCATION = "repeated_invocation"


class LambdaUrlProvider(ResourceProvider[LambdaUrlProperties]):
    TYPE = "AWS::Lambda::Url"  # Autogenerated. Don't change
    SCHEMA = util.get_schema_path(Path(__file__))  # Autogenerated. Don't change

    def create(
        self,
        request: ResourceRequest[LambdaUrlProperties],
    ) -> ProgressEvent[LambdaUrlProperties]:
        """
        Create a new resource.

        Primary identifier fields:
          - /properties/FunctionArn

        Required properties:
          - TargetFunctionArn
          - AuthType

        Create-only properties:
          - /properties/TargetFunctionArn
          - /properties/Qualifier

        Read-only properties:
          - /properties/FunctionUrl
          - /properties/FunctionArn

        IAM permissions required:
          - lambda:CreateFunctionUrlConfig

        """
        model = request.desired_state
        lambda_client = request.aws_client_factory.lambda_
        params = util.select_attributes(model, ["Qualifier", "Cors", "AuthType"])
        params["FunctionName"] = model["TargetFunctionArn"]

        response = lambda_client.create_function_url_config(**params)

        model["FunctionArn"] = response["FunctionArn"]
        model["FunctionUrl"] = response["FunctionUrl"]

        return ProgressEvent(
            status=OperationStatus.SUCCESS,
            resource_model=model,
            custom_context=request.custom_context,
        )

    def read(
        self,
        request: ResourceRequest[LambdaUrlProperties],
    ) -> ProgressEvent[LambdaUrlProperties]:
        """
        Fetch resource information

        IAM permissions required:
          - lambda:GetFunctionUrlConfig
        """
        raise NotImplementedError

    def delete(
        self,
        request: ResourceRequest[LambdaUrlProperties],
    ) -> ProgressEvent[LambdaUrlProperties]:
        """
        Delete a resource

        IAM permissions required:
          - lambda:DeleteFunctionUrlConfig
        """
        model = request.desired_state
        lambda_client = request.aws_client_factory.lambda_
        params = {"FunctionName": model["TargetFunctionArn"]}

        if qualifier := model.get("Qualifier"):
            params["Qualifier"] = qualifier

        lambda_client.delete_function_url_config(**params)

        return ProgressEvent(
            status=OperationStatus.SUCCESS,
            resource_model=model,
            custom_context=request.custom_context,
        )

    def update(
        self,
        request: ResourceRequest[LambdaUrlProperties],
    ) -> ProgressEvent[LambdaUrlProperties]:
        """
        Update a resource

        IAM permissions required:
          - lambda:UpdateFunctionUrlConfig
        """
        raise NotImplementedError
